﻿using FluentData;
using GFluentCode.Entity;
using GFluentCode.Tools;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace GFluentCode.ORM
{
    /// <summary>
    /// 实体操作基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class GFluentORMBase<T> : ORMBase where T : GFluentEntityBase, new()
    {
        #region 只读属性

        /// <summary>
        /// 实体对应表名
        /// </summary>
        public string TableName
        {
            get
            {
                return GFluentEntityBase.GetTableName<T>();
            }
        }

        /// <summary>
        /// 查询的列
        /// </summary>
        public string Columns
        {
            get
            {
                return GFluentEntityBase.GetColumns<T>();
            }
        }

        /// <summary>
        /// 主键，默认获取第一个主键或第一个字段
        /// </summary>
        public string PrimaryKey
        {
            get
            {
                return GFluentEntityBase.GetPrimaryKey<T>();
            }
        }
        #endregion

        #region 构造函数

        /// <summary>
        /// 根据配置文件生成I(默认使用加密)
        /// </summary>
        public GFluentORMBase() : base() { }
        /// <summary>
        /// 自选是否需要加密
        /// </summary>
        public GFluentORMBase(bool useEncryptDbString) : base(useEncryptDbString) { }

        /// <summary>
        /// 根据参数生成
        /// </summary>
        /// <param name="connectString"></param>
        /// <param name="dbType"></param>
        public GFluentORMBase(string connectString, EnDbType dbType) : base(connectString, dbType) { }

        #endregion

        #region T实体基本操作

        #region 查询

        /// <summary>
        /// 按条件查询是否存在
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public bool Exists(string where)
        {
            if (string.IsNullOrWhiteSpace(where)) throw new Exception("未填写判断条件");

            var i = DBaser.Sql($"Select count(*) From {TableName} Where {where}").QuerySingle<int>();
            return i > 0;
        }

        /// <summary>
        /// 查询所有实体
        /// </summary>
        /// <returns></returns>
        public IList<T> QueryAll()
        {
            return DBaser.Sql($"Select {Columns} From {TableName}").QueryMany<T>();
        }

        /// <summary>
        /// 查询单个实体
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public T QuerySingle(string where)
        {
            if (string.IsNullOrWhiteSpace(where)) throw new Exception("未填写判断条件");

            return DBaser.Sql($"Select {Columns} From {TableName} Where {where}").QuerySingle<T>();
        }

        /// <summary>
        /// 按条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public IList<T> Query(string where)
        {
            return DBaser.Sql($"Select {Columns} From {TableName} Where 1=1 {(string.IsNullOrWhiteSpace(where) ? "" : "And " + where)}")
                .QueryMany<T>();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public IList<T> QueryPage(string where, string order, int page, int size)
        {
            return DBaser.Select<T>($"{Columns}")
                .From(TableName)
                .Where(where)
                .OrderBy(order)
                .Paging(page, size)
                .QueryMany();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="fields"></param>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public IList<T> QueryPage(string fields, string where, string order, int page, int size)
        {
            return DBaser.Select<T>(fields)
                .From(TableName)
                .Where(where)
                .OrderBy(order)
                .Paging(page, size)
                .QueryMany();
        }
        #endregion

        #region 新增

        /// <summary>
        /// 新增返回主键
        /// </summary>
        /// <typeparam name="K">主键类型</typeparam>
        /// <param name="item"></param>
        /// <param name="idCol"></param>
        /// <param name="ignoreProperties"></param>
        /// <returns></returns>
        protected K Insert<K>(T item, string idCol, params Expression<Func<T, object>>[] ignoreProperties)
        {
            return DBaser.Insert(TableName, item).AutoMap(ignoreProperties).ExecuteReturnLastId<K>(idCol);
        }

        /// <summary>
        /// 新增 返回是否成功
        /// </summary>
        /// <param name="item"></param>
        /// <param name="ignoreProperties"></param>
        /// <returns></returns>
        protected bool Insert(T item, params Expression<Func<T, object>>[] ignoreProperties)
        {
            return DBaser.Insert(TableName, item).AutoMap(ignoreProperties).Execute() > 0;
        }

        /// <summary>
        /// 用sql语句添加，返回主键
        /// </summary>
        /// <typeparam name="K"></typeparam>
        /// <param name="sql"></param>
        /// <param name="idCol"></param>
        /// <returns></returns>
        protected K Insert<K>(string sql, string idCol)
        {
            return DBaser.Sql(sql).ExecuteReturnLastId<K>(idCol);
        }

        /// <summary>
        /// 用sql语句添加
        /// </summary>        
        /// <param name="sql"></param>        
        /// <returns></returns>
        protected bool Insert(string sql)
        {
            return DBaser.Sql(sql).Execute() > 0;
        }
        #endregion

        #region 修改

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="item"></param>
        /// <param name="where"></param>
        /// <param name="ignoreProperties"></param>
        /// <returns></returns>
        protected bool Update(T item, Expression<Func<T, object>> where, params Expression<Func<T, object>>[] ignoreProperties)
        {
            return DBaser.Update(TableName, item).AutoMap(ignoreProperties).Where(where).Execute() > 0;
        }

        /// <summary>
        /// 按sql语句添加
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        protected bool Update(string sql)
        {
            return DBaser.Sql(sql).Execute() > 0;
        }
        #endregion

        #region 删除

        /// <summary>
        /// 按默认主键删除
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        protected bool Delete(object value)
        {
            if (string.IsNullOrWhiteSpace(value.ToString())) throw new Exception("未设置删除键值");

            return DBaser.Delete(TableName).Where(PrimaryKey, value).Execute() > 0;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        protected bool Delete(string columnName, object value)
        {
            if (string.IsNullOrWhiteSpace(value.ToString())) throw new Exception("未设置删除键值");

            return DBaser.Delete(TableName).Where(columnName, value).Execute() > 0;
        }

        /// <summary>
        /// 根据删除条件删除
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        protected bool Delete(string where)
        {
            if (string.IsNullOrWhiteSpace(where)) throw new Exception("删除条件不能为空");

            return ExecuteReturnCount($"Delete From {TableName} Where {where}") > 0;
        }

        /// <summary>
        /// 删除，返回删除条数
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        protected int DeleteReturnCount(string columnName, object value)
        {
            if (string.IsNullOrWhiteSpace(value.ToString())) throw new Exception("未设置删除键值");

            return DBaser.Delete(TableName).Where(columnName, value).Execute();
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="item"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        protected bool Delete(T item, Expression<Func<T, object>> where)
        {
            return DBaser.Delete(TableName, item).Where(where).Execute() > 0;
        }

        /// <summary>
        /// 按表达式删除，返回删除条数
        /// </summary>
        /// <param name="item"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        protected int DeleteReturnCount(T item, Expression<Func<T, object>> where)
        {
            return DBaser.Delete(TableName, item).Where(where).Execute();
        }

        #endregion

        #endregion             
    }
}
